<?php
/**
 * Created by PhpStorm.
 * User: wenRuns
 * Date: 2020/12/25
 * Time: 9:22
 */

namespace WenRuns\Laravel\Admin\Form\Field\MultiList;


use Encore\Admin\Facades\Admin;
use Encore\Admin\Form\Field;

class MultiList extends Field
{
    use CommonMethods;

    const SYMBOL_BEGIN = 'QAQ';

    const SYMBOL_END = 'QAQ';

    /**
     * @var bool
     */
    protected $subMultiList = false;

    /**
     * 视图
     * @var string
     */
    protected $view = 'WenAdmin::form.multilist';

    /**
     * 唯一标识
     * @var string
     */
    protected $unique = '';

    /**
     * 表格对象
     * @var null
     */
    protected $tableList = null;

    /**
     * 表格回调函数
     * @var callable|null
     */
    protected $tableListClosure = null;


    /**
     * @var string
     */
    protected $index = '';

    /**
     * 数据格式化回调
     * @var null
     */
    protected $formatClosure = null;

    /**
     * $this->getTableList()->showButton($jsEventClosure);
     * @var bool
     */
    protected $jsEventClosure = null;

    /**
     * @var bool
     */
    protected $showButton = false;

    /**
     * @var bool
     */
    protected $disableEmpty = false;

    /**
     * @var bool
     */
    protected $enableInsertEleAfterActive = false;


    protected $oneRowScript = '';


    /**
     * MultiList constructor.
     * @param string $column
     * @param array $arguments
     */
    public function __construct($column = '', array $arguments = [])
    {
        $this->index = $arguments[2] ?? $column;
        if (is_callable($arguments[0])) {
            $this->tableListClosure = $arguments[0];
            $arguments[0] = $arguments[1] ?? '';
        }
        parent::__construct($column, $arguments);
    }

    public function subMultiList($bool = true)
    {
        $this->subMultiList = $bool;
        return $this;
    }

    /**
     * 设置格式化回调函数
     * @param \Closure $closure
     * @return $this
     */
    public function format(\Closure $closure)
    {
        $this->formatClosure = $closure;
        return $this;
    }

    /**
     * 填充数据
     * @param array $data
     */
    public function fill($data)
    {
        return parent::fill($data); // TODO: Change the autogenerated stub
    }

    /**
     * 获取表格对象
     * @param bool $isNew
     * @return TableList|null
     */
    public function getTableList($isNew = false)
    {
        if (empty($this->tableList) || $isNew) {
            $this->tableList = new TableList($this);
            if ($this->showButton) {
                $this->tableList->showButton($this->jsEventClosure)
                    ->enableInsertEleAfterActive($this->enableInsertEleAfterActive);
            }
            $this->tableList->setSubTableList($this->subMultiList)->withoutName($this->withoutName);
        }

        return $this->tableList;
    }

    /**
     * @param bool $enable
     * @return $this
     */
    public function enableInsertEleAfterActive($enable = true)
    {
        $this->enableInsertEleAfterActive = $enable;
        return $this;
    }


    /**
     * 引出empty展示框
     * @param bool $disable
     * @return $this
     */
    public function disableEmpty($disable = true)
    {
        $this->disableEmpty = $disable;
        return $this;
    }

    /**
     * 获取唯一标识
     * @return string
     */
    public function getUniqueKey()
    {
        if (empty($this->unique)) {
            $this->unique = md5(mt_rand(100000, 999999));
        }
        return $this->unique;
    }

    /**
     * 获取表单对象
     * @return \Encore\Admin\Form
     */
    public function getForm()
    {
        return $this->form;
    }

    /**
     * @return array
     */
    public function getOptions()
    {

        if (empty($this->options)) {
            $item = [];
            foreach ($this->tableList->columns as $column) {
                $item[$column->column] = '';
            }
            $this->options[] = $item;
        }
        return $this->options;
    }


    /**
     * 检测--值
     * @return mixed
     */
    protected function checkValue()
    {
//        $old = old($this->column);
//        if(!empty($old)){
////            dd($old);
//            return $old;
//        }
        if (empty($this->value) && $this->formatClosure) {
            $this->default = $this->formatClosure->call($this, $this->data);
            return $this->default;
        }
        return json_decode($this->value, true);
    }

    /**
     * 获取字段值
     * @return array|mixed
     */
    protected function getValues()
    {
        $default = $this->getDefault();
        if (empty($default)) {
            return is_array($this->value) ? $this->value : $this->checkValue();
        }
        return $default;
    }


    /**
     * 设置默认值
     * @param null $value
     * @return $this
     */
    protected function setOriginalValue($value = null)
    {
        if (empty($value)) {
            $values = $this->getValues();
            if (empty($values)) {
                return $this;
            }
            $data = current($values);
            if (is_array($data)) {
                $this->setOriginal([$this->column => $data]);
                $this->value($data);
                $this->default = $values;
            } else {
                $this->setOriginal([$this->column => $values]);
                $this->value($values);
                $this->default = [$values];
            }
            return $this;
        }
        $this->setOriginal([$this->column => $value]);
        $this->value($value);
        return $this;
    }

    /**
     * 输出内容
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|string
     */
    public function render()
    {
        if (!$this->shouldRender()) {
            return '';
        }
        if (empty($this->label)) {
            $width = $this->width['field'] + 2;
            $label = $this->width['label'] - 1;
            $width + $label > 12 ? $width = 12 - $label : null;
            $this->setWidth($width, $label);
        }
//        dd($this->getTableList()->getTableKey());
        $this->addVariables([
            '__content__' => $this->getContent(),
            'tableKey' => $this->getTableList()->getTableKey()
        ])
            ->addRequiredAttributeFromRules();
        Admin::script($this->script);
        return view($this->getView(), $this->variables());
    }


    protected function checkValues()
    {
//        if (!empty($this->value)) {
//            return $this->value;
//        }
//        if (!empty($this->default)) {
//            return $this->default;
//        }
        return $this->options;
    }

    /**
     * 获取文本内容
     * @return string
     */
    public function getContent()
    {
        $content = $this->setOriginalValue()
            ->checkTableListClosure()
            ->checkOptions()
            ->getTableList()
            ->tableListHead();
        $values = $this->checkValues();
        if (empty($values)) {
            $content .= $this->getTableList()->tbodyStart(true) . $this->emptyBody();
            $content .= $this->getTableList()->tableListEnd();
            return $content;
        } else {
            $content .= $this->getTableList()->tbodyStart();
        }
        $content .= $this->tableListBody($values);
        $content .= $this->getTableList()->tableListEnd();
        if ($this->createEmpty && empty($this->script)) {
            $this->oneRowScript = $this->getTableList()->getOneScript();
        }
        if (!$this->createEmpty && !in_array($this->getUniqueKey(), AddEvent::$registerMultiList)) {
            AddEvent::registerEvent($this);
        }
        return $content;
    }


    public function emptyBody()
    {
        if ($this->disableEmpty) {
            return '';
        }
        $colspan = $this->getTableList()->getColumnLen();

        return <<<HTML
<tr>
    <td colspan="{$colspan}" style="padding: 100px;text-align: center;color: #999999">
        <svg t="1562312016538" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2076" width="128" height="128" style="fill: #e9e9e9;">
            <path d="M512.8 198.5c12.2 0 22-9.8 22-22v-90c0-12.2-9.8-22-22-22s-22 9.8-22 22v90c0 12.2 9.9 22 22 22zM307 247.8c8.6 8.6 22.5 8.6 31.1 0 8.6-8.6 8.6-22.5 0-31.1L274.5 153c-8.6-8.6-22.5-8.6-31.1 0-8.6 8.6-8.6 22.5 0 31.1l63.6 63.7zM683.9 247.8c8.6 8.6 22.5 8.6 31.1 0l63.6-63.6c8.6-8.6 8.6-22.5 0-31.1-8.6-8.6-22.5-8.6-31.1 0l-63.6 63.6c-8.6 8.6-8.6 22.5 0 31.1zM927 679.9l-53.9-234.2c-2.8-9.9-4.9-20-6.9-30.1-3.7-18.2-19.9-31.9-39.2-31.9H197c-19.9 0-36.4 14.5-39.5 33.5-1 6.3-2.2 12.5-3.9 18.7L97 679.9v239.6c0 22.1 17.9 40 40 40h750c22.1 0 40-17.9 40-40V679.9z m-315-40c0 55.2-44.8 100-100 100s-100-44.8-100-100H149.6l42.5-193.3c2.4-8.5 3.8-16.7 4.8-22.9h630c2.2 11 4.5 21.8 7.6 32.7l39.8 183.5H612z" p-id="2077"></path>
        </svg>
    </td>
</tr>
HTML;

    }


    protected function checkOptions()
    {
        $values = $this->getValues();
        $this->options = array_filter(array_map(function ($option, $value) {
            if (empty($option) && empty($value)) {
                return null;
            }
            if (is_array($option) && is_array($value)) {
                return array_merge($option, $value);
            } elseif (empty($option) && !empty($value)) {
                return $value;
            }
            return $option;
        }, empty($this->options) ? [] : $this->options, empty($values) ? [] : $values));
        return $this;
    }


    /**
     * 检测表格回调函数
     * @param null $value
     * @param int $key
     * @return $this
     */
    protected function checkTableListClosure($key = 0)
    {
        if ($this->callback instanceof \Closure) {
            $this->value = $this->callback->call($this->form->model(), $this->value, $this);
        }
        $tableList = $this->getTableList(true)->value($this->value, $key);
        $this->tableListClosure && $this->tableListClosure->call($this, $tableList);
        return $this;
    }

    /**
     * @param array $options
     * @return $this|Field
     */
    public function options($options = [])
    {
        if (is_callable($options)) {
            $options = call_user_func($options, $this);
        }
        if ($options instanceof Arrayable) {
            $options = $options->toArray();
        }
        if (!$this->is2Array($options)) {
            $options = [$options];
        }

        $this->options = array_merge($this->options, $options);
        return $this;
    }

    /**
     * @param $arr
     * @return bool
     */
    protected function is2Array($arr)
    {
        if (isset($arr['subs'])) {
            return false;
        }
        return is_array(current($arr));
    }

    /**
     * @param null $jsCallback
     * @return $this
     */
    public function showButton($show = true, $jsCallback = null)
    {
        $this->showButton = $show;
        $this->jsEventClosure = $jsCallback;
        return $this;
    }

    /**
     * 生成表格体
     * @param $values
     * @return string
     */
    protected function tableListBody($values)
    {
        $content = '';
        if (empty($values)) {
            return $content;
        }
//        dd($values, $this->options);
        foreach ($values as $key => $item) {
            $content .= $this->setOriginalValue($item)
                ->checkTableListClosure($key)
                ->getTableList()
                ->keyIsVariable($this->keyIsVariable)
                ->createEmpty($this->createEmpty)
                ->tableListBody($key);
        }
        return $content;
    }

    /**
     * @return mixed|string
     */
    public function index()
    {
        return $this->index;
    }

    public function getOneRowScript()
    {
        return $this->oneRowScript;
    }

    /**
     * @param $name
     * @return |null
     */
    public function __get($name)
    {
        // TODO: Implement __get() method.
        return $this->original[$name] ?? null;
    }
}
